package main

import (
	"fmt"
	"google.golang.org/grpc"
	"log"
	"net"
	"order-srv/consul"
	"order-srv/docs"
	"order-srv/gateway"
	healthpb "order-srv/gen/health"
	userpb "order-srv/gen/user"
	"order-srv/handler"
	"order-srv/internal/biz"
	"order-srv/libs"
)

func Run() error {
	// 1
	// tcp连接配置，ip:port
	address := fmt.Sprintf("%s:%d", "0.0.0.0", libs.AppConfig.Port)
	lis, err := net.Listen("tcp", address)
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
		return err
	}

	// 创建grpc服务
	// 可以设置中间件，如：令牌校验中间件。
	var globalServerOptions []grpc.ServerOption
	server := grpc.NewServer(globalServerOptions...)
	// 注册健康检查服务
	healthpb.RegisterHealthServer(server, handler.NewHealthServer())
	// 注册用户服务
	userpb.RegisterUserServer(server, handler.NewUserService())
	// 设置健康检查服务
	consul.Health(server)
	log.Printf("grpc server listening at %v", lis.Addr())
	return server.Serve(lis)
}

// @title system API
// @version 1.0.0
// @description 系统级api.
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
func main() {
	// swagger config
	//docs.SwaggerInfo.Title = "system API"
	//docs.SwaggerInfo.Description = "系统级api."
	//docs.SwaggerInfo.Version = "1.0"
	//docs.SwaggerInfo.Host = addr
	docs.SwaggerInfo.Schemes = []string{"http", "https"}
	if libs.AppConfig.Env == "dev" {
		docs.SwaggerInfo.BasePath = ""
	} else {
		docs.SwaggerInfo.BasePath = "/system-api"
	}

	// 创建保存错误同步管道
	errChan := make(chan error)

	// 启动tcp服务，启动微服务
	go func() {
		// 注册服务到consul
		consul.ServiceRegisterMain()
		if err := Run(); err != nil {
			log.Fatalf("failed to serve: %v", err)
			// 写入错误
			errChan <- err
		}
	}()

	// 启动 http gateway 代理微服务,服务注册到consul
	go func() {
		consul.ServiceRegisterGateway()
		// 启动 rpc 网关
		if err := gateway.Run(); err != nil {
			// 写入错误
			errChan <- err
		}
	}()

	// 启动 业务服务
	go func() {
		consul.ServiceRegisterBiz()
		if err := biz.Run(); err != nil {
			// 写入错误
			errChan <- err
		}
	}()

	// 监听程序退出，实现优雅退出
	libs.Signal(func(err error) {
		errChan <- err // 一旦能读到信号，就说明有错误
	})

	// 同步通道，这里没有数据写入会一直阻塞，有数据写入继续执行
	getErr := <-errChan
	// 注销服务
	consul.ServiceDeregister()
	log.Printf("启动失败：%s", getErr.Error())
}
